using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CsharpAlgorithm;

namespace CsharpAlgorithm
{
    [TestClass]
    public class AlgorithmUnitTest
    {
        [TestMethod]
        public void Test_Uint()
        {
            uint umax = uint.MaxValue;
            uint umin = uint.MinValue;
            Assert.AreEqual(4294967295, umax - umin, "uint value ranges incorrect.");
            //umax = -2;
        }

        [TestMethod]
        public void Test_GetSubset()
        {
            SortedSet<int> set = new SortedSet<int>() { 5,2,3,4,1,7,9,0,12,11};
            List<SortedSet<int>> ret = AlgorithmLibrary.GetSubset(set);
            Assert.AreEqual<int>(1024, ret.Count+1, String.Format(
                "method doesn't return expected number of subsets. Expecting {0}, actual {1}", 1024, ret.Count + 1));

            //test 2
            SortedSet<int> set2 = new SortedSet<int>() { };
            List<SortedSet<int>> ret2 = AlgorithmLibrary.GetSubset(set2);
            Assert.AreEqual<int>(1, ret2.Count, String.Format("method doesn't return expected number of subsets. Expecting {0}, actual {1}", 0, ret));

        }

        [TestMethod]
        public void Test_CountChar_2()
        {
            string s = "aacbbca";
            Assert.AreEqual(2, AlgorithmLibrary.CountChar(s, 'c'));
        }

        [TestMethod]
        public void Test_CountChar_Method2()
        {
            string s = "2344fjfj4";
            Assert.AreEqual(3, AlgorithmLibrary.CountChar_Method2(s, '4'));
        }

        [TestMethod]
        public void Test_CountChar_Method3()
        {
            string s = "-2ddacabd";
            Assert.AreEqual(3, AlgorithmLibrary.CountChar_Method3(s, 'd'));
        }

        /// <summary>
        /// Multiple occurence of "starts", multiple occurence of "ends"
        /// </summary>
        [TestMethod]
        public void Test_Foo_SSEE()
        {
            String s1 = "HELLOWORLD";
            String s2 = "L";
            String s3 = "O";

            ArrayList actualResult = CsharpAlgorithm.AlgorithmLibrary.Foo(s1, s2, s3);

            Assert.AreEqual("LLOWO", actualResult[0] as String, true);  // last parameter ignore case
            Assert.AreEqual("LLO", actualResult[1] as String, true);
            Assert.AreEqual("LOWO", actualResult[2] as String, true);
            Assert.AreEqual("LO", actualResult[3] as String, true);
            Assert.AreEqual(4, actualResult.Count, "Length of result set doesn't match.");
        }

        [TestMethod]
        public void Test_AllUnique_null()
        {
            string s = string.Empty;
            Assert.AreEqual<bool>(true, CsharpAlgorithm.AlgorithmLibrary.AllUnique(s));
        }

        [TestMethod]
        public void Test_AllUnique_SingleChar()
        {
            string s = "s";
            Assert.AreEqual<bool>(true, CsharpAlgorithm.AlgorithmLibrary.AllUnique(s));
        }

        [TestMethod]
        public void Test_AllUnique_Yes()
        {
            string s = "abc";
            Assert.AreEqual<bool>(true, CsharpAlgorithm.AlgorithmLibrary.AllUnique(s));
        }

        [TestMethod]
        public void Test_AllUnique_No()
        {
            string s = "abca";
            Assert.AreEqual<bool>(false, CsharpAlgorithm.AlgorithmLibrary.AllUnique(s));
        }

        [TestMethod]
        public void Test_FindFirstUniqueChar_Single()
        {
            string s = "s";
            Assert.AreEqual('s', AlgorithmLibrary.FindFirstUniqueChar(s));
        }

        [TestMethod]
        public void Test_FindFirstUniqueChar_abcabcd()
        {
            string s = "abcabcd";
            Assert.AreEqual('d', AlgorithmLibrary.FindFirstUniqueChar(s));
        }

        [TestMethod]
        public void Test_FindFirstUniqueChar_emptyString()
        {
            string s = string.Empty;
            Assert.AreEqual('\0', AlgorithmLibrary.FindFirstUniqueChar(s));
        }

        [TestMethod]
        public void Test_ExtractNumbers_aa123b455()
        {
            string s = "aa123b455";
            List<int> result = AlgorithmLibrary.ExtractNumbers(s);

            Assert.AreEqual<int>(2, result.Count);
            Assert.AreEqual<int>(123, result[0]);
            Assert.AreEqual<int>(455, result[1]);
        }

        [TestMethod]
        public void Test_Permut_ABC()
        {
            char[] str = {'A', 'B', 'C'};
            List<string> permutations = AlgorithmLibrary.Permut(str);

            Assert.AreEqual(6, permutations.Count);
            Assert.AreEqual("ABC", permutations[0], true);
            Assert.AreEqual("BAC", permutations[1], true);
            Assert.AreEqual("BCA", permutations[2], true);
            Assert.AreEqual("ACB", permutations[3], true);
            Assert.AreEqual("CAB", permutations[4], true);
            Assert.AreEqual("CBA", permutations[5], true);
        }

        [TestMethod]
        public void Test_Permut_SingleCharacter()
        {
            char[] str = {'a'};
            List<string> permutations = AlgorithmLibrary.Permut(str);
            Assert.AreEqual(1, permutations.Count);
            Assert.AreEqual("a", permutations[0], true);
        }

        [TestMethod]
        public void Test_Permut_Space()
        {
            char[] str = { ' '};

            List<string> permutations = AlgorithmLibrary.Permut(str);

            Assert.AreEqual<int>(0, permutations.Count);

        }

        [TestMethod]
        public void Test_GCD_12_18()
        {
            int max = 18, min = 12;
            Assert.AreEqual(6, AlgorithmLibrary.GCD(max, min));
        }

        [TestMethod]
        public void Test_GCD_0_5()
        {
            int max = 5, min = 0;
            Assert.AreEqual(5, AlgorithmLibrary.GCD(max, min));
        }

        [TestMethod]
        public void Test_GCD_5_0()
        {
            int max = 0, min = 5;
            Assert.AreEqual(5, AlgorithmLibrary.GCD(max, min));
        }

        [TestMethod]
        public void Test_GCD_12_9()
        {
            // one odd, one even 
            int max = 12, min = 9;
            Assert.AreEqual(3, AlgorithmLibrary.GCD(max, min));
        }

        [TestMethod]
        public void Test_GCD_9_27()
        {
            int max = 9, min = 27;
            Assert.AreEqual(9, AlgorithmLibrary.GCD(max, min));
        }
    }
}